package com.yuelan.apartment.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yuelan.apartment.common.BillType;
import com.yuelan.apartment.common.Constant;
import com.yuelan.apartment.common.RoomStatus;
import com.yuelan.apartment.domain.ApaRoom;
import com.yuelan.apartment.domain.ApaTenant;
import com.yuelan.apartment.domain.ApaTenantLog;
import com.yuelan.apartment.domain.dto.ApaRentBillDto;
import com.yuelan.apartment.domain.dto.ApaTenantDto;
import com.yuelan.apartment.domain.vo.ApaTenantVo;
import com.yuelan.apartment.mapper.ApaApartmentMapper;
import com.yuelan.apartment.mapper.ApaTenantLogMapper;
import com.yuelan.apartment.mapper.ApaTenantMapper;
import com.yuelan.apartment.service.ApaRentService;
import com.yuelan.apartment.service.ApaRoomService;
import com.yuelan.apartment.service.ApaTenantService;
import com.yuelan.common.constant.HttpStatus;
import com.yuelan.common.core.page.TableDataInfo;
import com.yuelan.common.core.redis.RedisCache;
import com.yuelan.common.exception.GlobalException;
import com.yuelan.common.exception.ServiceException;
import com.yuelan.common.utils.DateUtils;
import com.yuelan.common.utils.SecurityUtils;
import com.yuelan.common.utils.uuid.IdWorker;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;


/**
 * @description: 租户管理
 * @Author: ZhaoYi
 * @date: 24-5-23 17:00
 */
@Service
public class ApaTenantServiceImpl implements ApaTenantService {

    @Resource
    private ApaTenantMapper apaTenantMapper;
    @Resource
    private ApaRoomService apaRoomService;
    @Resource
    private RedisCache redisCache;
    @Resource
    private ApaRentService apaRentService;
    @Resource
    private ApaTenantLogMapper apaTenantLogMapper;
    @Resource
    private ApaApartmentMapper apaApartmentMapper;

    private static final Logger logger = LoggerFactory.getLogger(GlobalException.class);


    @Transactional
    @Override
    public int add(ApaTenantDto tenantDto) {
        tenantDto.setId(IdWorker.snowflake());
        tenantDto.setCreateTime(DateUtils.getNowDate());
        // 新增房间
        apaRoomService.addRoom(getRoomInfo(tenantDto));
        // 房客是否已存在
        LambdaQueryWrapper<ApaTenant> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ApaTenant::getPhone, tenantDto.getPhone())
                .eq(ApaTenant::getIdNumber, tenantDto.getIdNumber());
        ApaTenant apaTenant = apaTenantMapper.selectOne(queryWrapper);
        if (apaTenant != null) {
            throw new ServiceException(Constant.TENANT_SERVICE_EXIST);
        }
        // 房客入住登记
        apaTenantLogMapper.insert(getApaTenantLog(tenantDto));
        // 生成账单
        apaRentService.createRentBill(getRentBillInfo(tenantDto));
        // 生成房客信息
        return apaTenantMapper.insert(getTenantInfo(tenantDto));
    }

    private ApaTenantLog getApaTenantLog(ApaTenantDto tenantDto) {
        ApaTenantLog apaTenantLog = new ApaTenantLog();
        apaTenantLog.setId(IdWorker.snowflake());
        apaTenantLog.setTenantName(tenantDto.getTenantName());
        apaTenantLog.setPhone(tenantDto.getPhone());
        apaTenantLog.setRoomNum(tenantDto.getRoomNum());
        String apartmentName = apaApartmentMapper
                .selectById(tenantDto.getApartmentId())
                .getApartmentName();
        apaTenantLog.setApartmentName(apartmentName);
        apaTenantLog.setJoinTime(DateUtils.getNowDate());
        return apaTenantLog;
    }

    private ApaTenant getTenantInfo(ApaTenantDto tenantDto) {
        ApaTenant apaTenant = new ApaTenant();
        apaTenant.setId(tenantDto.getId());
        apaTenant.setRoomNum(tenantDto.getRoomNum());
        apaTenant.setTenantName(tenantDto.getTenantName());
        apaTenant.setPhone(tenantDto.getPhone());
        apaTenant.setIdNumber(tenantDto.getIdNumber());
        apaTenant.setApartmentId(tenantDto.getApartmentId());
        return apaTenant;
    }

    private ApaRentBillDto getRentBillInfo(ApaTenantDto tenantDto) {
        ApaRentBillDto rentBillDto = new ApaRentBillDto();
        rentBillDto.setId(tenantDto.getId());
        rentBillDto.setApartmentId(tenantDto.getApartmentId());
        rentBillDto.setTenantId(tenantDto.getId());
        rentBillDto.setRoomNum(tenantDto.getRoomNum());
        rentBillDto.setCollectionTime(tenantDto.getCollectionTime());
        rentBillDto.setRent(tenantDto.getRent());
        rentBillDto.setPaymentType(tenantDto.getPaymentType());
        rentBillDto.setStatus(BillType.Uncollected.getStatus());
        rentBillDto.setCreateTime(DateUtils.getNowDate());
        rentBillDto.setContractEndDate(tenantDto.getPeriodTime());
        return rentBillDto;
    }

    private ApaRoom getRoomInfo(ApaTenantDto tenantDto) {
        ApaRoom apaRoom = new ApaRoom();
        apaRoom.setTenantId(tenantDto.getId());
        apaRoom.setRoomNum(tenantDto.getRoomNum());
        apaRoom.setApartmentId(tenantDto.getApartmentId());
        apaRoom.setStatus(RoomStatus.Hiring.getStatus());
        apaRoom.setArea(tenantDto.getArea());
        apaRoom.setType(tenantDto.getType());
        return apaRoom;
    }


    @Override
    public TableDataInfo page(ApaTenant apaTenant) {
        List<ApaTenantVo> apaTenantVoList = apaTenantMapper
                .selectTenant(SecurityUtils.getUsername());
        Integer total = apaTenantMapper.total(SecurityUtils.getUsername());
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setRows(apaTenantVoList);
        rspData.setTotal(total);
        return rspData;
    }


    @Transactional
    @Override
    public int deleteTenantByIds(Long[] ids) {
        if (ids == null) {
            throw new ServiceException(Constant.SERVICE_ERROR);
        }
        // 登记房客退租时间
        LambdaUpdateWrapper<ApaTenantLog> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(ApaTenantLog::getId, ids);
        updateWrapper.set(ApaTenantLog::getLoseTime, DateUtils.getDate());
        apaTenantLogMapper.update(updateWrapper);
        // 清除房客
        apaRoomService.updateRoomState(ids);
        return apaTenantMapper.deleteTenantByIds(ids);
    }


    @Transactional
    @Override
    public int update(ApaTenant apaTenant) {
        LambdaUpdateWrapper<ApaTenant> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.setEntity(apaTenant);
        return apaTenantMapper.update(updateWrapper);
    }


    @Override
    public ApaTenant load(Long id) {
        if (id == null) {
            throw new ServiceException(Constant.SERVICE_ERROR);
        }
        return apaTenantMapper.selectById(id);
    }


    @Override
    public List<ApaTenantVo> exportData() {
        return apaTenantMapper.export(SecurityUtils.getUsername());
    }


}
